package com.itbaizhan.shopping_manager_api.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

//Security配置类
@Configuration
//开启鉴权配置注解
@EnableMethodSecurity
public class SecurityConfig  {

    //Spring Security 配置
    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        //自定义表单登录
        http.formLogin()
                .usernameParameter("username") //用户名项
                .passwordParameter("password") //密码项
                .loginProcessingUrl("/admin/login") //登录提交路径
                .successHandler(new MyLoginSuccessHandler()) //登录成功处理器
                .failureHandler(new MyLoginFailHandler()); //登陆失败处理器

        //权限拦截配置
        http.authorizeHttpRequests()
                .requestMatchers("/login","/admin/login").permitAll()//登录不需要认证
                .anyRequest().authenticated(); //其余都需要认证

        //退出登录配置
        http.logout()
                .logoutUrl("/admin/logout") //注销路径
                .logoutSuccessHandler(new MyLogoutSuccessHandler()) //注销成功处理器
                .clearAuthentication(true) //清除认证数据
                .invalidateHttpSession(true); //清除session

        //异常处理
        http.exceptionHandling()
                .authenticationEntryPoint(new MyAuthenticationEntryPoint()) //未登录处理器
                .accessDeniedHandler(new MyAccessDeniedHandler());//权限不足处理器


        //关闭csrf防护
        http.csrf().disable();

        //开启跨域访问
        http.cors();

        http.sessionManagement()
                .maximumSessions(1);//最大并发会话数，后面登录的会踢掉旧的会话（即同一个账号只能在一个浏览器上登录）

        return http.build();
    }

    //密码加密
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
